/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package main;

import services.ServiceInformation;
import exportFile.ExportExcel;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;

import dataModel.jsonReader.JSONReader;
import dataModel.jsonStructure.Doc;
import dataModel.process.Activity;
import dataModel.process.ProcessModel;
import de.hpi.bpt.graph.algo.rpst.RPST;
import de.hpi.bpt.process.ControlFlow;
import de.hpi.bpt.process.Node;
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import preprocessing.FormatConverter;
import de.hpi.bpt.process.Process;
import screen.HeuristicsSelected;
import services.IdentifyingHeuristics;

/**
 *
 * @author Bruna
 */
public class Main {
    
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws Exception{
                
        // Load and generate from JSON files in directory
        createFromDirectory();        
        
    }
    
    /**
     * Loads JSON files from directory and writes generated texts (incl. figure) into a PDF
     */
    private static void createFromDirectory() throws JsonSyntaxException, IOException {
        //String path = "JsonFile/AnalisarPedidoDeCredito - Signavio.json";
        String path = "JsonFile/AnalisarPedidoDeCredito - Signavio3.json";

        JSONReader reader = new JSONReader();
        Gson gson = new Gson();

        int counter = 0;
        Doc modelDoc = gson.fromJson(reader.getJSONStringFromFile(path), Doc.class);
        if (modelDoc.getChildShapes() != null) {
            try {
                reader.init();
                reader.getIntermediateProcessFromFile(modelDoc);
                ProcessModel model = reader.getProcessModelFromIntermediate();
                try {
                    model.normalize();
                    model.normalizeEndEvents();
                } catch (Exception e) {
                    System.out.println("Error: Normalization impossible");
                    e.printStackTrace();
                }
                
                ExportExcel file = new ExportExcel();
                file.setOutputFile("ExcelFile/services.xls");
                
                ExportExcel fileServConsol = new ExportExcel();
                fileServConsol.setOutputFile("ExcelFile/servicesConsolidated.xls");
                
                List<List> allServices = new LinkedList<List>();
                List<ServiceInformation> servicesInfos = new LinkedList<ServiceInformation>();
                
                System.out.println("-----//  Regras de Negócio  //-----");
                servicesInfos = IdentifyingHeuristics.findBusinessRules(model);
                if(!servicesInfos.isEmpty()){
                    //List<ServiceInformation> listServicesBusinessRule = IdentifyingHeuristics.deleteSameServices(servicesInfos);
                    //allServices.add(listServicesBusinessRule);
                    allServices.add(servicesInfos);
                }                
                
                System.out.println("-----//  Multipla Instância  //-----");
                servicesInfos = IdentifyingHeuristics.findMultipleInstance(model);
                if(!servicesInfos.isEmpty()){
                    //List<ServiceInformation> listServicesMultipleInstance = IdentifyingHeuristics.deleteSameServices(servicesInfos);
                    //allServices.add(listServicesMultipleInstance);
                    allServices.add(servicesInfos);
                }
                
                System.out.println("-----//  Data Store  //-----");
                servicesInfos = IdentifyingHeuristics.findDataStore(model);
                List<ServiceInformation> finalClusterConsolidated = new LinkedList<ServiceInformation>();
                if(!servicesInfos.isEmpty()){
                    //List<ServiceInformation> listServicesCluster = IdentifyingHeuristics.deleteSameServices(servicesInfos);
                    List<ServiceInformation> listAuxServicesCluster = new LinkedList<ServiceInformation>();
                    //listAuxServicesCluster.addAll(listServicesCluster);
                    listAuxServicesCluster.addAll(servicesInfos);
                    finalClusterConsolidated = IdentifyingHeuristics.consolidateClusterServices(listAuxServicesCluster);
                    //allServices.add(finalClusterServices);
                    //allServices.add(listServicesCluster);
                    allServices.add(servicesInfos);
                }
                
                IdentifyingHeuristics.transformToAdjancencyList(model);
                
                System.out.println("-----//  Atividades Sequenciais  //-----");
                List<List> ativsSeq = IdentifyingHeuristics.findSequentialActivities(model);
                List<List> servicesActivities = new LinkedList<List>();
                servicesActivities = IdentifyingHeuristics.printAndSetSequentialActivities(ativsSeq, model);
                for (List list : servicesActivities) {
                    //List<ServiceInformation> activitiesList = list;
                    //List<ServiceInformation> listSequenceActivities = IdentifyingHeuristics.deleteSameServices(activitiesList);
                    //allServices.add(listSequenceActivities);
                    allServices.add(list);
                }                
                
                RPST<ControlFlow,Node> rpst = transformToRPST(model, counter);
                
                System.out.println("-----//  Heuristica de Workflow  //-----");
                
                List<ServiceInformation> servicesWorkflow = new LinkedList<ServiceInformation>();
                IdentifyingHeuristics.findWokflowHeuristic(rpst.getRoot(), rpst,0,model,servicesWorkflow);
                
                List<ServiceInformation> listServicesWorkflow = IdentifyingHeuristics.deleteSameServices(servicesWorkflow);
                listServicesWorkflow = IdentifyingHeuristics.countSubflows(listServicesWorkflow);
                
                allServices.add(listServicesWorkflow);
                
                HeuristicsSelected heurisSelec = new HeuristicsSelected();
                file.write(allServices,heurisSelec);
                
                List<List> servicesClusterConsolidated = new LinkedList<List>();
                servicesClusterConsolidated.add(finalClusterConsolidated);
                
                HashMap<Integer, Activity> allActivities = model.getActivities();
                List<String> actsName = new LinkedList<String>();
                List<String> actsRepeatName = new LinkedList<String>();
                
                
                for(int keyMap: allActivities.keySet()){                
                    actsName.add(allActivities.get(keyMap).getLabel());
                }
                
                for(int i = 0; i<actsName.size(); i++){
                    for(int j = i+1; j<actsName.size(); j++){
                    
                        if(actsName.get(i).equalsIgnoreCase(actsName.get(j))){
                            actsRepeatName.add(actsName.get(i));
                        }
                    }
                    
                }
                actsName.removeAll(actsRepeatName);
                actsName.addAll(actsRepeatName);
                
                HeuristicsSelected heurisSelecConsol = new HeuristicsSelected();
                fileServConsol.writeConsolidated(servicesClusterConsolidated, allServices, actsName, heurisSelecConsol);
                
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
    public static RPST transformToRPST(ProcessModel model, int counter){        
        // Convert to RPST
	FormatConverter formatConverter = new FormatConverter();
	Process p = formatConverter.transformToRPSTFormat(model);
	RPST<ControlFlow,Node> rpst = new RPST<ControlFlow,Node>(p);        
        return rpst;        
    }  
    
    
}
